import {
  Button,
  Col,
  Dropdown,
  Form,
  FormItem,
  Input,
  InputPassword,
  InputSearch,
  Menu,
  MenuItem,
  Modal,
  RadioGroup,
  Row,
  Select,
  Space,
  Spin,
  Switch,
  Textarea,
  Tree,
  TreeSelect,
  Upload
} from 'ant-design-vue'
import { omit, omitBy, set } from 'lodash-unified'
import { defineComponent, onMounted, ref } from 'vue'

import { dictApi, userApi } from '@/apis'
import { ProTable } from '@/components'
import { TABLE_FORMAT, TABLE_ITEM_RENDER, TABLE_RENDERER } from '@/constants'
import { TableOptions, useTableRef, useUpload } from '@/hooks'
import { dictToOptions } from '@/utils'

import { useDept, useFormData, useOperation, useToolbar } from './hooks'
import styles from './index.module.css'
import { UserFormType } from './types'

export default defineComponent({
  name: 'UserView',
  setup() {
    const statusOptions = ref([] as OptionItem[])
    const sexOptions = ref([] as OptionItem[])
    const selectedIds = ref(new Set<string>())
    const tableConfig = ref({
      showOverflow: true,
      border: true,
      loading: false,
      toolbarConfig: {
        custom: true,
        refresh: true,
        zoom: true,
        slots: {
          buttons: 'toolbar_buttons'
        }
      },
      formConfig: {
        items: [
          {
            field: 'useName',
            title: '用户名称',
            itemRender: {
              name: TABLE_ITEM_RENDER.AInput,
              props: {
                placeholder: '请输入用户名称'
              }
            }
          },
          {
            field: 'phone',
            title: '手机号码',
            itemRender: {
              name: TABLE_ITEM_RENDER.AInput,
              props: {
                placeholder: '请输入手机号码'
              }
            }
          },
          {
            field: 'status',
            title: '状态',
            itemRender: {
              name: TABLE_ITEM_RENDER.ASelect,
              props: {
                placeholder: '用户状态'
              }
            }
          },
          {
            field: 'createTime',
            title: '创建时间',
            itemRender: {
              name: TABLE_RENDERER.FormItemDate,
              props: {
                type: 'range',
                placeholder: ['开始时间', '结束时间'],
                valueFormat: 'YYYY-MM-DD',
                keys: ['beginDate', 'endDate']
              }
            }
          },
          {
            itemRender: {
              name: TABLE_RENDERER.FormItemBtns
            }
          }
        ]
      },
      columns: [
        { type: 'checkbox', width: 50 },
        {
          field: 'userId',
          title: '用户编号'
        },
        {
          field: 'userName',
          title: '用户名称'
        },
        {
          field: 'nickName',
          title: '用户昵称'
        },
        {
          field: 'dept',
          title: '部门',
          formatter: ({ row }) => row.dept?.deptName
        },
        {
          field: 'phone',
          title: '手机号码'
        },
        {
          field: 'status',
          title: '状态',
          slots: {
            default: 'status'
          }
        },
        {
          field: 'createTime',
          title: '创建时间',
          formatter: TABLE_FORMAT.Date
        },
        {
          title: '操作',
          width: 140,
          slots: {
            default: 'operation'
          }
        }
      ],
      pagerConfig: {
        pageSize: 15
      },
      proxyConfig: {
        seq: true,
        form: true,
        props: {
          result: 'list',
          total: 'total'
        },
        ajax: {
          query: async ({ page, form }) => {
            form = processingData(form)

            const data = await userApi.getUserPage({
              pageSize: page.pageSize,
              pageNum: page.currentPage,
              ...form
            })
            return data
          }
        }
      },
      onCheckboxChange({ checked, row }) {
        checked
          ? selectedIds.value.add(row.infoId)
          : selectedIds.value.delete(row.infoId)
      }
    } as TableOptions)

    const tableRefHook = useTableRef(tableConfig)

    const { selectedKeys, getDeptTree, ...deptRestHook } = useDept({
      tableRefHook
    })
    const { getFormData, ...formDataRestHook } = useFormData()
    const operationHook = useOperation({
      getFormData,
      tableRefHook
    })
    const toolbarHook = useToolbar({
      getFormData,
      tableRefHook
    })
    const { uploadHeaders } = useUpload()

    function processingData(data: any) {
      data = omit(data, ['createTime'])
      data = omitBy(data, value => {
        return value === null
      })

      if (selectedKeys.value) {
        set(data, 'deptId', selectedKeys.value)
      }

      return data
    }

    async function init() {
      const [dictStatus, dictSex] = await Promise.all([
        dictApi.getDictDataList('sys_normal_disable'),
        dictApi.getDictDataList('sys_user_sex'),
        getDeptTree()
      ])

      statusOptions.value = dictToOptions(dictStatus)
      sexOptions.value = dictToOptions(dictSex)

      tableRefHook.updateFormItem({
        field: 'status',
        key: 'itemRender.props.options',
        value: statusOptions.value
      })
    }

    onMounted(() => {
      init()
    })

    return {
      statusOptions,
      sexOptions,
      selectedIds,
      tableRef: tableRefHook.tableRef,
      tableConfig,
      uploadHeaders,
      ...deptRestHook,
      ...formDataRestHook,
      ...operationHook,
      ...toolbarHook
    }
  },
  render() {
    const renderForm = (type: UserFormType) => {
      const formModel = type === 'add' ? this.addFormModel : this.editFormModel
      const formRef = type === 'add' ? this.addFormRef : this.editFormRef

      return (
        <Modal
          title={type === 'add' ? '添加用户' : '修改用户'}
          visible={type === 'add' ? this.showAdd : this.showEdit}
          confirmLoading={type === 'add' ? this.addLoading : this.editLoading}
          width={600}
          onOk={type === 'add' ? this.handleAdd : this.handleEdit}
          onCancel={type === 'add' ? this.handleCloseAdd : this.handleCloseEdit}
          destroyOnClose
        >
          <Spin spinning={this.dataLoading}>
            <Form labelCol={{ span: 4 }}>
              <Row>
                <Col span={12}>
                  <FormItem
                    label={'用户昵称'}
                    labelCol={{ span: 8 }}
                    {...formRef.validateInfos['nickName']}
                  >
                    <Input
                      v-model:value={formModel.nickName}
                      placeholder={'请输入用户昵称'}
                    />
                  </FormItem>
                </Col>
                <Col span={12}>
                  <FormItem label={'归属部门'} labelCol={{ span: 8 }}>
                    <TreeSelect
                      v-model:value={formModel.deptId}
                      treeData={this.deptTree}
                      fieldNames={{
                        children: 'children',
                        label: 'title',
                        value: 'key'
                      }}
                      allowClear
                      placeholder={'请选择归属部门'}
                    />
                  </FormItem>
                </Col>
              </Row>
              <Row>
                <Col span={12}>
                  <FormItem label={'手机号码'} labelCol={{ span: 8 }}>
                    <Input
                      v-model:value={formModel.phone}
                      placeholder={'请输入手机号码'}
                    />
                  </FormItem>
                </Col>
                <Col span={12}>
                  <FormItem label={'邮箱'} labelCol={{ span: 8 }}>
                    <Input
                      v-model:value={formModel.email}
                      placeholder={'请输入邮箱'}
                    />
                  </FormItem>
                </Col>
              </Row>
              {type === 'add' ? (
                <Row>
                  <Col span={12}>
                    <FormItem
                      label={'用户名称'}
                      labelCol={{ span: 8 }}
                      {...formRef.validateInfos['userName']}
                    >
                      <Input
                        v-model:value={formModel.userName}
                        placeholder={'请输入用户名称'}
                      />
                    </FormItem>
                  </Col>
                  <Col span={12}>
                    <FormItem
                      label={'用户密码'}
                      labelCol={{ span: 8 }}
                      {...formRef.validateInfos['password']}
                    >
                      <InputPassword
                        v-model:value={formModel.password}
                        placeholder={'请输入用户密码'}
                      />
                    </FormItem>
                  </Col>
                </Row>
              ) : null}
              <Row>
                <Col span={12}>
                  <FormItem label={'用户性别'} labelCol={{ span: 8 }}>
                    <Select
                      v-model:value={formModel.sex}
                      options={this.sexOptions}
                      placeholder="请选择性别"
                    ></Select>
                  </FormItem>
                </Col>
                <Col span={12}>
                  <FormItem label={'状态'} labelCol={{ span: 8 }}>
                    <RadioGroup
                      v-model:value={formModel.status}
                      options={this.statusOptions}
                    ></RadioGroup>
                  </FormItem>
                </Col>
              </Row>
              <Row>
                <Col span={12}>
                  <FormItem label={'岗位'} labelCol={{ span: 8 }}>
                    <Select
                      v-model:value={formModel.postIds}
                      mode={'multiple'}
                      maxTagCount={1}
                      options={this.postOptions}
                      placeholder={'请选择岗位'}
                    ></Select>
                  </FormItem>
                </Col>
                <Col span={12}>
                  <FormItem label={'角色'} labelCol={{ span: 8 }}>
                    <Select
                      v-model:value={formModel.roleIds}
                      mode={'multiple'}
                      maxTagCount={1}
                      options={this.roleOptions}
                      placeholder={'请选择角色'}
                    ></Select>
                  </FormItem>
                </Col>
              </Row>
              <FormItem label={'备注'}>
                <Textarea
                  v-model:value={formModel.remark}
                  placeholder={'请输入内容'}
                />
              </FormItem>
            </Form>
          </Spin>
        </Modal>
      )
    }

    return (
      <div>
        <Row gutter={20}>
          <Col span={5}>
            <InputSearch
              v-model:value={this.searchValue}
              placeholder={'请输入部门名称'}
              style={{
                marginTop: '6px',
                marginBottom: '10px'
              }}
            />
            <Spin spinning={this.treeLoading}>
              {this.deptTree.length > 0 ? (
                <Tree
                  treeData={this.deptTree}
                  defaultExpandAll
                  onSelect={this.handleSelect}
                />
              ) : (
                <div class={styles.emptyTree}></div>
              )}
            </Spin>
          </Col>
          <Col span={19}>
            <ProTable
              ref="tableRef"
              v-slots={{
                toolbar_buttons: () => (
                  <Space>
                    <Button
                      v-permission="system:user:add"
                      type={'primary'}
                      ghost
                      onClick={this.handleShowAdd}
                    >
                      新增
                    </Button>
                    <Button
                      v-permission="system:user:remove"
                      danger
                      ghost
                      disabled={this.selectedIds.size === 0}
                    >
                      删除
                    </Button>
                    <Button
                      v-permission="system:user:import"
                      type={'primary'}
                      ghost
                      onClick={this.handleShowImport}
                    >
                      导入
                    </Button>
                    <Button
                      v-permission="system:user:export"
                      type={'primary'}
                      ghost
                      disabled={!this.canExport}
                      onClick={this.handleExport}
                    >
                      导出
                    </Button>
                  </Space>
                ),
                status: ({ row }) => (
                  <Switch
                    v-model:checked={row.status}
                    checkedValue={'0'}
                    unCheckedValue={'1'}
                    onChange={() => this.handleToggleStatus(row)}
                  ></Switch>
                ),
                operation: ({ row }) =>
                  row.userId !== '1' ? (
                    <Space size={'small'}>
                      <Button
                        v-permission="system:user:edit"
                        type={'link'}
                        size={'small'}
                        onClick={() => this.handleShowEdit(row)}
                      >
                        修改
                      </Button>
                      <Button
                        v-permission="system:user:remove"
                        type={'link'}
                        size={'small'}
                        onClick={() => this.handleDelete(row.userId)}
                      >
                        删除
                      </Button>
                      <Dropdown
                        v-slots={{
                          default: () => (
                            <Button type={'link'} size={'small'}>
                              更多
                            </Button>
                          ),
                          overlay: () => (
                            <Menu>
                              <MenuItem>
                                <Button
                                  v-permission="system:user:resetPwd"
                                  type={'link'}
                                  size={'small'}
                                  onClick={() =>
                                    this.handleShowReset(row.userId)
                                  }
                                >
                                  重置密码
                                </Button>
                              </MenuItem>
                            </Menu>
                          )
                        }}
                      />
                    </Space>
                  ) : null
              }}
              {...this.tableConfig}
            />
          </Col>
        </Row>
        {/* 添加弹窗 */}
        {renderForm('add')}
        {/* 修改弹窗 */}
        {renderForm('edit')}
        {/* 导入弹窗 */}
        <Modal
          title={'用户导入'}
          visible={this.showImport}
          confirmLoading={this.importLoading}
          onCancel={this.handleCloseImport}
          destroyOnClose
        >
          <div class={styles.uploadContent}>
            <Upload
              action={'/api/system/user/template/import'}
              accept={'.xls,.xlsx'}
              headers={this.uploadHeaders}
              maxCount={1}
              showUploadList={false}
              onChange={this.handleUploadTemplateChange}
            >
              <Button loading={this.importLoading}>上传</Button>
            </Upload>
            <div style={{ marginTop: '10px' }}>
              <span>仅允许导入xls、xlsx格式文件。</span>
              <Button
                type={'link'}
                size={'small'}
                onClick={this.handleTemplate}
              >
                下载模板
              </Button>
            </div>
          </div>
        </Modal>
        {/* 重置弹窗 */}
        <Modal
          title={'重置密码'}
          visible={this.showReset}
          confirmLoading={this.resetLoading}
          onOk={this.handleReset}
          onCancel={this.handleCloseReset}
          destroyOnClose
        >
          <Form>
            <FormItem {...this.resetFormRef.validateInfos['password']}>
              <Input
                v-model:value={this.resetFormModel.password}
                placeholder="请输入新密码"
              />
            </FormItem>
          </Form>
        </Modal>
      </div>
    )
  }
})
